package study2018.com.xtianzhuang.www.luncene;

import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class FileIndexReader {
	// 索引保存路径
	private static final String INDEX_PATH = "D:\\study\\luncene\\index";

	public static void main(String[] args) throws IOException, ParseException {
		// 搜索的索引路径，lucene提供了两种索引存放的位置，
		// 一种是磁盘(FSDirectory)，一种是内存(RAMDirectory)。一般情况将索引放在磁盘上
		File file = new File(INDEX_PATH);
		// 1.创建Directory，根据IndexReader创建IndexSearcher(搜索器)
		Directory directory = FSDirectory.open(file);
		// 2.创建Analyzer,设定分析器，必须与建立索引时采用的分析器相同
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
		// 3.创建IndexReader
		IndexReader reader = IndexReader.open(directory); // 打开存储位置
		IndexSearcher searcher = new IndexSearcher(reader);

		String queryString = "绝对秋香"; // 搜索的关键词
		try {
			// 4.创建搜索的Query,确定搜索的内容
			// 使用QueryParser完成解析搜索请求，
			// new QueryParser(version,Field字段， 分析器) ,Field字段为进行搜索的范围。
			QueryParser qp = new QueryParser(Version.LUCENE_36, "content", analyzer);
			// Query对所传入的搜索关键词汇进行解释，并返回query对象。
			// 我们需要把查询String封装成Query才可以交给Searcher来搜索。
			// lucene中支持模糊查询，语义查询，短语查询，组合查询等等,
			// 如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。
			Query query = qp.parse(queryString);
			// Query query = QueryParser.parser(“要查询的字串”)

			if (searcher != null) {
				// 5.根据searcher搜索并且返回TopDocs
				// 老版本中的Hits已经被弃用,代替它的是TopDocs，
				// 这个对象封装了那些最符合搜索条件的结果的信息
				TopDocs results = searcher.search(query, 10); // 返回搜索相似度最高的10条记录
				// ScoreDoc是一个评分对象，因为lucene在搜索过程中，给每一个资源都评分，
				// 然后按照分数高低来决定最符合的搜索条件的结果,这个对象同样存了这些结果的信息
				// 6.根据TopDocs获取ScoreDoc对象
				ScoreDoc[] hits = results.scoreDocs; // 用于保存搜索结果
				// 打印搜索结果
				if (hits.length > 0) {
					System.out.println("找到:" + hits.length + " 个结果!");
					for (int i = 0; i < hits.length; i++) {
						// 7.根据search和ScordDoc对象获取具体的Document对象
						Document hitDoc = searcher.doc(hits[i].doc);
						System.out.println("____________________________");
						// 8.根据Document对象获取需要的值
						System.out.println(hitDoc.get("path"));
						System.out.println(hitDoc.get("context"));
						System.out.println("____________________________\n");
					}
				}
				reader.close();
				directory.close();
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}
